package com.example.exjnidemo.exusb;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.Toast;
import com.jbh.permissionlibrary.PermissionManager;
import com.jbh.permissionlibrary.i.CheckPermissionListener;
import com.jbh.permissionlibrary.i.PermissionRequestCode;
import com.jiangdg.usbcamera.UVCCameraHelper;
import com.jiangdg.usbcamera.utils.FileUtils;
import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.common.AbstractUVCCameraHandler;
import com.serenegiant.usb.encoder.RecordParams;
import com.serenegiant.usb.widget.CameraViewInterface;
import com.serenegiant.usb.widget.UVCCameraTextureView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent {

    private UVCCameraTextureView mTextureView;
    private UVCCameraHelper mCameraHelper;
    private CameraViewInterface mUVCCameraView;
    private AlertDialog mDialog;
    private boolean isRequest;
    private boolean isPreview;
    /*录制控制开关*/
    private Switch mSwitchVoice ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        init();
    }


    private void initView() {
        mSwitchVoice = findViewById(R.id.switch_rec_voice);
        mTextureView = findViewById(R.id.camera_view);
    }


    /**
     * 展示预览画面和停止
     */
    private CameraViewInterface.Callback mCallback = new CameraViewInterface.Callback(){

        @Override
        public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
            // 开始预览
            if (!isPreview && mCameraHelper.isCameraOpened()) {
                mCameraHelper.startPreview(mUVCCameraView);
                isPreview = true;
            }
        }

        @Override
        public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) {

        }

        @Override
        public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
            // 停止预览
            if (isPreview && mCameraHelper.isCameraOpened()) {
                mCameraHelper.stopPreview();
                isPreview = false;
            }
        }
    };



    /***
     * 检测usb 插入 拔出  连接  断开
     */
    private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {

        @Override
        public void onAttachDev(UsbDevice device) {
            showShortMsg("onAttachDev");
            // request open permission(must have)
            if (!isRequest) {
                isRequest = true;
                if (mCameraHelper != null) {
                    mCameraHelper.requestPermission(0);
                }
            }
        }

        @Override
        public void onDettachDev(UsbDevice device) {
            showShortMsg("onDettachDev close camera(must have)");
            if (isRequest) {
                isRequest = false;
                mCameraHelper.closeCamera();
            }
        }

        @Override
        public void onConnectDev(UsbDevice device, boolean isConnected) {
            if (!isConnected) {
                showShortMsg("fail to connect,please check resolution params");
                isPreview = false;
            } else {
                isPreview = true;
                showShortMsg("connecting");
                // initialize seekbar
                // need to wait UVCCamera initialize over
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Looper.prepare();

                        if (isHavCameraHelper()){
                            /*默认的对比度和美艳*/
//                            mSeekBrightness.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_BRIGHTNESS));
//                            mSeekContrast.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_CONTRAST));
                        }
                        Looper.loop();
                    }
                }).start();
            }
        }

        @Override
        public void onDisConnectDev(UsbDevice device) {
            showShortMsg("disconnecting");
        }
    };



    @Override
    public USBMonitor getUSBMonitor() {
        return mCameraHelper.getUSBMonitor();
    }


    @Override
    public void onDialogResult(boolean canceled) {
        if (canceled) {
            showShortMsg("取消操作");
        }
    }

    private void showShortMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }




    /*****************************************/
    /**           toolBar右边菜单            **/
    /*****************************************/
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_toobar, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_takepic:
                PermissionManager.newInstance().checkPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        PermissionRequestCode.WRITE_EXTERNAL_STORAGE_REQUEST_CODE,
                        new CheckPermissionListener() {
                            @Override
                            public void onNoNeedCheckPermission() {
                                takePic();
                            }
                        });
                break;
            case R.id.menu_recording:
                List<String> list = new ArrayList<>();
                list.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                list.add(Manifest.permission.RECORD_AUDIO);
                PermissionManager.newInstance().checkPermission(MainActivity.this,
                        list,
                        10,
                        new CheckPermissionListener() {
                            @Override
                            public void onNoNeedCheckPermission() {
                                recording();
                            }
                        });
                break;
            case R.id.menu_focus:
                focusUVCCamera();
                break;
            case R.id.menu_resolution:
                resolutionCheck();
                break;
        }
        return super.onOptionsItemSelected(item);
    }


    /**
     * 分辨率的选择
     */
    private void resolutionCheck() {
        showResolutionListDialog();
    }


    /**
     * 对焦UVCCamera
     *
     */
    private void focusUVCCamera() {
        if (!isHavCameraHelper())return;
        mCameraHelper.startCameraFoucs();
    }


    /**
     * 录制视频
     */
    private void recording() {
        if (!isHavCameraHelper())return;
        if (!mCameraHelper.isPushing()) {
            String videoPath = UVCCameraHelper.ROOT_PATH + MyApplication.DIRECTORY_NAME +"/videos/" + System.currentTimeMillis()
                    + UVCCameraHelper.SUFFIX_MP4;

            // FileUtils.createfile(FileUtils.ROOT_PATH + "test666.h264");
            // if you want to record,please create RecordParams like this
            RecordParams params = new RecordParams();
            /**
             * 录制保存的位置
             */
            params.setRecordPath(videoPath);
            // auto divide saved,default 0 means not divided
            params.setRecordDuration(0);
            /**
             * 录制开关
             */
            params.setVoiceClose(mSwitchVoice.isChecked());
            // overlay only support armeabi-v7a & arm64-v8a
//            params.setSupportOverlay(true);

            mCameraHelper.startPusher(params,
                    new AbstractUVCCameraHandler.OnEncodeResultListener() {
                @Override
                public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) {
                    // type = 1,h264 video stream
                    if (type == 1) {
                        FileUtils.putFileStream(data, offset, length);
                    }
                    // type = 0,aac audio stream
                    if(type == 0) {

                    }
                }
                @Override
                public void onRecordResult(String videoPath) {
                    if(TextUtils.isEmpty(videoPath)) {
                        return;
                    }
                    new Handler(getMainLooper()).post(() -> Toast.makeText(MainActivity.this,
                            "save videoPath:"+videoPath, Toast.LENGTH_SHORT).show());
                }
            });
            // if you only want to push stream,please call like this
            // mCameraHelper.startPusher(listener);
            showShortMsg("start record...");
            mSwitchVoice.setEnabled(false);
        } else {
            FileUtils.releaseFile();
            mCameraHelper.stopPusher();
            showShortMsg("stop record...");
            mSwitchVoice.setEnabled(true);
        }
    }



    /**
     * 拍照
     */
    private void takePic() {
        if (!isHavCameraHelper())return;

        String picPath = UVCCameraHelper.ROOT_PATH + MyApplication.DIRECTORY_NAME +"/images/"
                + System.currentTimeMillis() + UVCCameraHelper.SUFFIX_JPEG;

        mCameraHelper.capturePicture(picPath, new AbstractUVCCameraHandler.OnCaptureListener() {
            @Override
            public void onCaptureResult(String path) {

                if(TextUtils.isEmpty(path)) {
                    return;
                }

                new Handler(getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "save path:"+path, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

    }


    /**
     * 帮助类是否为空
     *
     * UVCCamera是否开启
     *
     * @return
     */
    public boolean isHavCameraHelper(){
        if (mCameraHelper == null || !mCameraHelper.isCameraOpened()) {
            showShortMsg("sorry,camera open failed");
            return false;
        }
        return true ;
    }




    /*****************************************/
    /**           弹出显示预览尺寸            **/
    /*****************************************/
    private void showResolutionListDialog() {
        if (!isHavCameraHelper())return;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        View rootView = LayoutInflater.from(this).inflate(R.layout.layout_dialog_list, null);
        ListView listView = (ListView) rootView.findViewById(R.id.listview_dialog);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getResolutionList());
        if (adapter != null) {
            listView.setAdapter(adapter);
        }
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened())
                    return;
                final String resolution = (String) adapterView.getItemAtPosition(position);
                String[] tmp = resolution.split("x");
                if (tmp != null && tmp.length >= 2) {
                    int widht = Integer.valueOf(tmp[0]);
                    int height = Integer.valueOf(tmp[1]);
                    mCameraHelper.updateResolution(widht, height);
                }
                mDialog.dismiss();
            }
        });
        builder.setView(rootView);
        mDialog = builder.create();
        mDialog.show();
    }




    /**
     * 获取设备支持的尺寸
     *
     * @return
     */
    private List<String> getResolutionList() {
        List<Size> list = mCameraHelper.getSupportedPreviewSizes();
        List<String> resolutions = null;
        if (list != null && list.size() != 0) {
            resolutions = new ArrayList<>();
            for (Size size : list) {
                if (size != null) {
                    resolutions.add(size.width + "x" + size.height);
                }
            }
        }
        return resolutions;
    }



    private void init() {
        // step.1 initialize UVCCameraHelper
        mUVCCameraView = (CameraViewInterface) mTextureView;
        mUVCCameraView.setCallback(mCallback);
        /**获取帮助类*/
        mCameraHelper = UVCCameraHelper.getInstance();
        /**默认设置分辨率*/
        mCameraHelper.setDefaultPreviewSize(1280,720);
        /**默认使用的是FRAME_FORMAT_MJPEG，如果使用UVCCameraHelper.FRAME_FORMAT_MJPEG不能录制MP4视频  请尝试使用UVCCameraHelper.FRAME_FORMAT_YU*/
//         mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV);
        /**初始化帮助类*/
        mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);

        mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() {
            @Override
            public void onPreviewResult(byte[] nv21Yuv) {
                Log.d("[PreviewFrame]->", "onPreviewResult: "+nv21Yuv.length);
            }
        });
    }



    @Override
    protected void onStart() {
        super.onStart();
        // step.2 register USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.registerUSB();
        }
    }



    @Override
    protected void onStop() {
        super.onStop();
        // step.3 unregister USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.unregisterUSB();
        }
    }

    /**
     * 销毁界面的释放资源处理
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        FileUtils.releaseFile();
        // step.4 release uvc camera resources
        if (mCameraHelper != null) {
            mCameraHelper.release();
        }
    }
}